/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using System.Threading.Tasks;
using System;

namespace NetProtocol.Server {
	/// <summary>
	/// 大厅房间匹配模块
	/// module : room
	/// </summary>
	public interface SNetRoom : INetServerModule {
		Dictionary<int, MessageHandler> INetServerModule.GetModuleFunction()
        {	
            return new()
            {
                { NetMessageId.room_createRoom, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_createRoom, "Recv->" + data.ToString());
#endif
		                CreateRoomRequest _data = (CreateRoomRequest)data;
						return CS_createRoom(session);
		            } 
            	},
                { NetMessageId.room_leaveRoom, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_leaveRoom, "Recv->" + data.ToString());
#endif
		                LeaveRoomRequest _data = (LeaveRoomRequest)data;
						return CS_leaveRoom(session, _data.roomId);
		            } 
            	},
                { NetMessageId.room_joinRoom, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_joinRoom, "Recv->" + data.ToString());
#endif
		                JoinRoomRequest _data = (JoinRoomRequest)data;
						return CS_joinRoom(session, _data.roomId);
		            } 
            	},
                { NetMessageId.room_requestMatch, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_requestMatch, "Recv->" + data.ToString());
#endif
		                RequestMatchRequest _data = (RequestMatchRequest)data;
						return CS_requestMatch(session, _data.requestPod);
		            } 
            	},
                { NetMessageId.room_cancelMatch, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_cancelMatch, "Recv->" + data.ToString());
#endif
		                CancelMatchRequest _data = (CancelMatchRequest)data;
						return CS_cancelMatch(session);
		            } 
            	},
                { NetMessageId.room_changeLevel, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_changeLevel, "Recv->" + data.ToString());
#endif
		                ChangeLevelRequest _data = (ChangeLevelRequest)data;
		                CS_changeLevel(session, _data.levelCid);
		                return VoidMessageResult.Instance;
		            } 
            	},
                { NetMessageId.room_requestEnter, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_requestEnter, "Recv->" + data.ToString());
#endif
		                RequestEnterRequest _data = (RequestEnterRequest)data;
		                CS_requestEnter(session, _data.levelCid);
		                return VoidMessageResult.Instance;
		            } 
            	},
                { NetMessageId.room_kickoutPlayer, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_kickoutPlayer, "Recv->" + data.ToString());
#endif
		                KickoutPlayerRequest _data = (KickoutPlayerRequest)data;
		                CS_kickoutPlayer(session, _data.targetPid);
		                return VoidMessageResult.Instance;
		            } 
            	},
                { NetMessageId.room_closeSeat, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_closeSeat, "Recv->" + data.ToString());
#endif
		                CloseSeatRequest _data = (CloseSeatRequest)data;
		                CS_closeSeat(session, _data.seatNum);
		                return VoidMessageResult.Instance;
		            } 
            	},
                { NetMessageId.room_openSeat, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.room_openSeat, "Recv->" + data.ToString());
#endif
		                OpenSeatRequest _data = (OpenSeatRequest)data;
		                CS_openSeat(session, _data.seatNum);
		                return VoidMessageResult.Instance;
		            } 
            	},
            };
        }
        
        Dictionary<int, Func<IReceiveMessage>> INetServerModule.GetModuleRequest() 
        {
	        return new ()
	        {
	        	{NetMessageId.room_createRoom, ()=> new CreateRoomRequest()},
	        	{NetMessageId.room_leaveRoom, ()=> new LeaveRoomRequest()},
	        	{NetMessageId.room_joinRoom, ()=> new JoinRoomRequest()},
	        	{NetMessageId.room_requestMatch, ()=> new RequestMatchRequest()},
	        	{NetMessageId.room_cancelMatch, ()=> new CancelMatchRequest()},
	        	{NetMessageId.room_changeLevel, ()=> new ChangeLevelRequest()},
	        	{NetMessageId.room_requestEnter, ()=> new RequestEnterRequest()},
	        	{NetMessageId.room_kickoutPlayer, ()=> new KickoutPlayerRequest()},
	        	{NetMessageId.room_closeSeat, ()=> new CloseSeatRequest()},
	        	{NetMessageId.room_openSeat, ()=> new OpenSeatRequest()},
	        };
	    }
        
#region Server-side Interface
		/// <summary>
        ///  创建房间
        /// </summary>
	    protected CreateRoomResult CS_createRoom(ISession session);
		/// <summary>
        ///  离开房间，roomId用于校验
        /// </summary>
	    protected LeaveRoomResult CS_leaveRoom(ISession session, long roomId);
		/// <summary>
        ///  请求加入房间
        /// </summary>
	    protected JoinRoomResult CS_joinRoom(ISession session, long roomId);
		/// <summary>
        ///  匹配可能有筛选参数
        /// </summary>
	    protected RequestMatchResult CS_requestMatch(ISession session, MatchRequestPOD requestPod);
		/// <summary>
        /// 
        /// </summary>
	    protected CancelMatchResult CS_cancelMatch(ISession session);
		/// <summary>
        ///  变更房间关卡，0表示取消指定
        /// </summary>
    	protected bool CS_changeLevel(ISession session, int levelCid);
		/// <summary>
        ///  请求进入关卡，可能进入非当前关卡 -- 暂不制作进入确认
        /// </summary>
    	protected bool CS_requestEnter(ISession session, int levelCid);
		/// <summary>
        ///  踢出指定玩家，房主可操作 -- 以下协议暂不制作
        /// </summary>
    	protected bool CS_kickoutPlayer(ISession session, long targetPid);
		/// <summary>
        ///  关闭座位	
        /// </summary>
    	protected bool CS_closeSeat(ISession session, int seatNum);
		/// <summary>
        ///  开启座位
        /// </summary>
    	protected bool CS_openSeat(ISession session, int seatNum);
#endregion
#region Client-side Interface
		/// <summary>
        /// 
        /// </summary>
		public bool SC_notifyRoomInfo(ISession session, RoomPOD roomPod, RoomActionReason reason){
	        return NetProtocolHelper.SendMessage(session, new NotifyRoomInfo(roomPod, reason));
	    }
	    public void SC_notifyRoomInfo_Broadcast(List<ISession> sessions, RoomPOD roomPod, RoomActionReason reason){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyRoomInfo(roomPod, reason));
	    }
		/// <summary>
        /// 
        /// </summary>
		public bool SC_notifyRoomSimpleInfo(ISession session, RoomPOD roomPod, RoomActionReason reason){
	        return NetProtocolHelper.SendMessage(session, new NotifyRoomSimpleInfo(roomPod, reason));
	    }
	    public void SC_notifyRoomSimpleInfo_Broadcast(List<ISession> sessions, RoomPOD roomPod, RoomActionReason reason){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyRoomSimpleInfo(roomPod, reason));
	    }
		/// <summary>
        /// 
        /// </summary>
		public bool SC_notifyMatchState(ISession session, MatchStatePOD matchStatePOD, RoomMatchReason reason){
	        return NetProtocolHelper.SendMessage(session, new NotifyMatchState(matchStatePOD, reason));
	    }
	    public void SC_notifyMatchState_Broadcast(List<ISession> sessions, MatchStatePOD matchStatePOD, RoomMatchReason reason){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyMatchState(matchStatePOD, reason));
	    }
		/// <summary>
        ///  该协议仅用于提示；roomId用于校验	
        /// </summary>
        public CreateRoomResult SC_createRoomResult(Task<CreateRoomResult> future){return new CreateRoomResult(future);}
        public CreateRoomResult SC_createRoomResult(int code, long roomId){return new CreateRoomResult(code, roomId);}
        public CreateRoomResult SC_createRoomResult(int code){return new CreateRoomResult(code);}
		/// <summary>
        ///  该协议仅用于提示
        /// </summary>
        public LeaveRoomResult SC_leaveRoomResult(Task<LeaveRoomResult> future){return new LeaveRoomResult(future);}
        public LeaveRoomResult SC_leaveRoomResult(int code){return new LeaveRoomResult(code);}
		/// <summary>
        ///  该协议仅用于提示
        /// </summary>
        public JoinRoomResult SC_joinRoomResult(Task<JoinRoomResult> future){return new JoinRoomResult(future);}
        public JoinRoomResult SC_joinRoomResult(int code){return new JoinRoomResult(code);}
		/// <summary>
        ///  该协议仅用于提示
        /// </summary>
        public RequestMatchResult SC_requestMatchResult(Task<RequestMatchResult> future){return new RequestMatchResult(future);}
        public RequestMatchResult SC_requestMatchResult(int code){return new RequestMatchResult(code);}
		/// <summary>
        ///  该协议仅用于提示
        /// </summary>
        public CancelMatchResult SC_cancelMatchResult(Task<CancelMatchResult> future){return new CancelMatchResult(future);}
        public CancelMatchResult SC_cancelMatchResult(int code){return new CancelMatchResult(code);}
#endregion

#region Messages
	public class NotifyRoomInfo : MessageNotify {
		private RoomPOD roomPod;
		private RoomActionReason reason;
		public NotifyRoomInfo(RoomPOD roomPod, RoomActionReason reason) {
		    this.roomPod = roomPod;
		    this.reason = reason;
		}
		public override int GetMessageId() {return NetMessageId.room_notifyRoomInfo;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.room_notifyRoomInfo;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(roomPod);
			_out.Write_byte((sbyte)reason);
			return si_p;
		}
		public override string ToString() {
			return "Room.SC_notifyRoomInfo { "
			+ "roomPod="
			+ roomPod
			+ ", reason="
			+ reason
			+" }";
		}
	}
	public class NotifyRoomSimpleInfo : MessageNotify {
		private RoomPOD roomPod;
		private RoomActionReason reason;
		public NotifyRoomSimpleInfo(RoomPOD roomPod, RoomActionReason reason) {
		    this.roomPod = roomPod;
		    this.reason = reason;
		}
		public override int GetMessageId() {return NetMessageId.room_notifyRoomSimpleInfo;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.room_notifyRoomSimpleInfo;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(roomPod);
			_out.Write_byte((sbyte)reason);
			return si_p;
		}
		public override string ToString() {
			return "Room.SC_notifyRoomSimpleInfo { "
			+ "roomPod="
			+ roomPod
			+ ", reason="
			+ reason
			+" }";
		}
	}
	public class NotifyMatchState : MessageNotify {
		private MatchStatePOD matchStatePOD;
		private RoomMatchReason reason;
		public NotifyMatchState(MatchStatePOD matchStatePOD, RoomMatchReason reason) {
		    this.matchStatePOD = matchStatePOD;
		    this.reason = reason;
		}
		public override int GetMessageId() {return NetMessageId.room_notifyMatchState;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.room_notifyMatchState;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(matchStatePOD);
			_out.Write_byte((sbyte)reason);
			return si_p;
		}
		public override string ToString() {
			return "Room.SC_notifyMatchState { "
			+ "matchStatePOD="
			+ matchStatePOD
			+ ", reason="
			+ reason
			+" }";
		}
	}
	public class CreateRoomResult : MessageResult {
	    private long roomId;
	    public CreateRoomResult(Task<CreateRoomResult> future): base(future) { }
		public CreateRoomResult(int code): base(code) { }
		public new CreateRoomResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
	    internal CreateRoomResult(int code, long roomId){
	        this.code = code;
	        this.roomId = roomId;
	    }
        public override MessageResult GetFutureResult(Task task) { return ((Task<CreateRoomResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.room_createRoomResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.room_createRoomResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			_out.Write_long(roomId);
			return si_p;
		}
		public override string ToString() {
    		return "Room.SC_createRoomResult { "
			+ "code="
			+ code
			+ ", roomId="
			+ roomId
			+" }";
		}
	}
	public class LeaveRoomResult : MessageResult {
	    public LeaveRoomResult(Task<LeaveRoomResult> future): base(future) { }
		public LeaveRoomResult(int code): base(code) { }
		public new LeaveRoomResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<LeaveRoomResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.room_leaveRoomResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.room_leaveRoomResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "Room.SC_leaveRoomResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	public class JoinRoomResult : MessageResult {
	    public JoinRoomResult(Task<JoinRoomResult> future): base(future) { }
		public JoinRoomResult(int code): base(code) { }
		public new JoinRoomResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<JoinRoomResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.room_joinRoomResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.room_joinRoomResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "Room.SC_joinRoomResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	public class RequestMatchResult : MessageResult {
	    public RequestMatchResult(Task<RequestMatchResult> future): base(future) { }
		public RequestMatchResult(int code): base(code) { }
		public new RequestMatchResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<RequestMatchResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.room_requestMatchResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.room_requestMatchResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "Room.SC_requestMatchResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	public class CancelMatchResult : MessageResult {
	    public CancelMatchResult(Task<CancelMatchResult> future): base(future) { }
		public CancelMatchResult(int code): base(code) { }
		public new CancelMatchResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<CancelMatchResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.room_cancelMatchResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.room_cancelMatchResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "Room.SC_cancelMatchResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	private class CreateRoomRequest : IReceiveMessage
    {
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
		}
        public int GetMessageId() { return NetMessageId.room_createRoom; }
        public override string ToString()
        {
            return "Room.createRoom";
        }
    }
	private class LeaveRoomRequest : IReceiveMessage
    {
		internal long roomId;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            roomId = _in.HasRemaining() ? _in.Read_long() : default;
		}
        public int GetMessageId() { return NetMessageId.room_leaveRoom; }
        public override string ToString()
        {
            return "Room.leaveRoom"+ ", roomId="+ roomId;
        }
    }
	private class JoinRoomRequest : IReceiveMessage
    {
		internal long roomId;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            roomId = _in.HasRemaining() ? _in.Read_long() : default;
		}
        public int GetMessageId() { return NetMessageId.room_joinRoom; }
        public override string ToString()
        {
            return "Room.joinRoom"+ ", roomId="+ roomId;
        }
    }
	private class RequestMatchRequest : IReceiveMessage
    {
		internal MatchRequestPOD requestPod;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            requestPod = _in.HasRemaining() ? _in.Read_pod<MatchRequestPOD>(MatchRequestPOD.DynamicFactory) : default;
		}
        public int GetMessageId() { return NetMessageId.room_requestMatch; }
        public override string ToString()
        {
            return "Room.requestMatch"+ ", requestPod="+ requestPod;
        }
    }
	private class CancelMatchRequest : IReceiveMessage
    {
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
		}
        public int GetMessageId() { return NetMessageId.room_cancelMatch; }
        public override string ToString()
        {
            return "Room.cancelMatch";
        }
    }
	private class ChangeLevelRequest : IReceiveMessage
    {
		internal int levelCid;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            levelCid = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.room_changeLevel; }
        public override string ToString()
        {
            return "Room.changeLevel"+ ", levelCid="+ levelCid;
        }
    }
	private class RequestEnterRequest : IReceiveMessage
    {
		internal int levelCid;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            levelCid = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.room_requestEnter; }
        public override string ToString()
        {
            return "Room.requestEnter"+ ", levelCid="+ levelCid;
        }
    }
	private class KickoutPlayerRequest : IReceiveMessage
    {
		internal long targetPid;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            targetPid = _in.HasRemaining() ? _in.Read_long() : default;
		}
        public int GetMessageId() { return NetMessageId.room_kickoutPlayer; }
        public override string ToString()
        {
            return "Room.kickoutPlayer"+ ", targetPid="+ targetPid;
        }
    }
	private class CloseSeatRequest : IReceiveMessage
    {
		internal int seatNum;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            seatNum = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.room_closeSeat; }
        public override string ToString()
        {
            return "Room.closeSeat"+ ", seatNum="+ seatNum;
        }
    }
	private class OpenSeatRequest : IReceiveMessage
    {
		internal int seatNum;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            seatNum = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.room_openSeat; }
        public override string ToString()
        {
            return "Room.openSeat"+ ", seatNum="+ seatNum;
        }
    }
	}
#endregion
}